Raspberry Pi 的C++交叉编译环境配置 (3)

上一节我们把交叉编译的环境配置好了,但是作为开发过程来讲尤其是从被Visual Studio开发环境懒惯了的人来讲,用编辑器开发用命令编译工作效率还是太低。幸好M$在15年推出了 visual studio code ,本质上讲它只是一款编辑器,但是配合上插件和配置脚本后可以让Linux开发和在Windows上的体验几乎一致。

一个vscode管理的项目大致包含一下结构

vscode-configure

组成 作用
extension 插件,用来添加相应语言的功能
makefile 编译管理工具
cpp source 源文件
task.json vscode 的任务管理
launch.json 调试配置管理
keyborad.json 快捷键

到vscode官网下载Ubuntu适用的最新安装包

vscode

在Ubuntu上安装后打开,界面是这样的

vscode-look

vscode 是以目录为项目管理单位的,点击 open folder 来打开一个目录,如果没有的话就新建一个。

首先安装插件:

启动 VS Code 快速打开功能 Ctrl+P, 粘贴命令并回车.

1
ext install cpptools

cpptools是用来编辑C++代码的插件,提供代码格式化、函数补完、调试等功能。具体参见这里

插件安装完成后,用新建文件的方式创建代码,我写了一些测试代码可以点击创建后把下面这些代码粘上去。

点击这个按钮新建文件

  • Makefile - makefile是Unix下常用的管理工程的工具,点击这里有比较详细的教程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    objects = test.o list.o
    ver =
    CC=arm-linux-gnueabihf-gcc
    CXX=arm-linux-gnueabihf-g++
    ifeq ($(ver), debug)
    CXXFLAGS = -c -Wall -g -Ddebug -pthread -std=c++11 -I~/raspberrypi/rootfs/usr/include -L~/raspberrypi/rootfs/lib/arm-linux-gnueabihf
    filename = testapp_d
    else
    CXXFLAGS = -c -Wall -O3 -pthread -std=c++11 -I~/raspberrypi/rootfs/usr/include -L~/raspberrypi/rootfs/lib/arm-linux-gnueabihf
    filename = testapp
    endif
    all : $(objects)
    $(CXX) -Wall -pthread -std=c++11 -o $(filename) $^
    debug: $(objects)
    $(CXX) -g -Wall -pthread -std=c++11 -o $(filename) $^
    test.o : test.cpp
    $(CXX) $(CXXFLAGS) $< -o $@
    list.o: list.cpp
    $(CXX) $(CXXFLAGS) $< -o $@
    clean :
    rm -f $(filename) $(filename)_d *.o

  • list.h

    1
    2
    3
    4
    5
    6
    7
    #ifndef LIST_H
    #define LIST_H
    #include<iostream>
    void printWelcome();
    void my_thread();
    #endif

  • list.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include "list.h"
    void printWelcome( )
    {
    std::cout<<"Welcome"<<std::endl;
    }
    void my_thread()
    {
    puts("hello, thread!");
    }

  • test.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include<iostream>
    #include<stdio.h>
    #include<string>
    #include<thread>
    #include "list.h"
    using namespace std;
    int main( int argc, char* argv[])
    {
    std::thread t( [](){ puts("Hello, Lambda thread!"); });
    string strInfo = "";
    cout<<"Hello Test!"<<endl;
    printWelcome();
    float szChara = 8.0;
    int sum=0;
    for( int i=0; i<10;i++)
    {
    sum+=i;
    }
    int size = sizeof(szChara);
    cout<< "size of char: "<< size << endl;
    t.join();
    return 0;
    }

源文件和makefile添加完成后,我们开始配置task.json用来管理任务

在vscode中按 Ctrl+Shift+B vscode-config-task

然后点击

vscode-config-task1

vscode会在工程目录下新建.vscode 文件夹,并声称 task.json文件。

将我配置好的task.json内容复制上去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"taskName": "debug",
"type": "shell",
"command": "make ver=debug debug",
"suppressTaskName": true,
"group": "build",
"presentation": {
"reveal": "always",
"panel": "shared"
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceRoot}"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "make",
"fileLocation": [
"relative",
"${workspaceRoot}"
],
"pattern": {
"regexp": "^(.*):(\\d+):\\s+(.*)$",
"file": 1,
"line": 2,
"message": 3
}
}
]
},
{
"taskName": "remote debug",
"type": "shell",
"command": "./prepare_remote_debug.sh",
"suppressTaskName": true,
"group": "build",
"presentation": {
"reveal": "always",
"focus": false,
"panel": "shared"
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceRoot}"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "make",
"fileLocation": [
"relative",
"${workspaceRoot}"
],
"pattern": {
"regexp": "^(.*):(\\d+):\\s+(.*)$",
"file": 1,
"line": 2,
"message": 3
}
}
]
},
{
"taskName": "release",
"type": "shell",
"command": "make",
"suppressTaskName": true,
"group": "build",
"presentation": {
"reveal": "always",
"focus": false,
"panel": "shared"
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceRoot}"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "make",
"fileLocation": [
"relative",
"${workspaceRoot}"
],
"pattern": {
"regexp": "^(.*):(\\d+):\\s+(.*)$",
"file": 1,
"line": 2,
"message": 3
}
}
]
},
{
"taskName": "clean",
"type": "shell",
"command": "make clean",
"suppressTaskName": true,
"group": "build",
"presentation": {
"reveal": "always",
"focus": false,
"panel": "shared"
},
"problemMatcher": []
}
]
}

vscode 的task 本质上是在后台执行一个command,我们利用配置task调用make 实现管理编译工程文件及其他任务,task的语法可以参考这里

现在,我们可以利用task来实现项目的编译。

在vscode中按 Ctrl+P 调出快速命令 输入 task debug 回车进行编译,控制台中输出:

vscode-task-debug

此时make工具会执行 make ver=debug debug命令来对工程进行编译,编译结束后在文件夹下生成test.o 及 testapp_d文件。

同样,可以利用task执行make clean, vscode中 按 Ctrl+P 输入 task clean,回车执行清理。

现在可以说开发编译过程非常方便了,但是还可以更方便一点。

在标题栏中找到 File - Preferrences-Keyboard shortcuts 点击后打开Keyboard shortcuts页面,点击keybindings.json

vscode-keybinding

点击后弹出

vscode-keybinding1

在Keybindings.json中输入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
[
{
"key": "F7",
"command": "workbench.action.tasks.runTask",
"args": "debug"
},
{
"key": "ctrl+F7",
"command": "workbench.action.tasks.runTask",
"args": "remote debug"
}
]

keybindings.json是定义快捷键的布局文件,这里我们添加了 F7Ctrl+F7 分别执行 task debugtask remote debug ,debug任务实际上是执行带调试信息的编译任务并不是真正的debug。

好了现在可以关掉keybindings.json回到我们的工程中来,按下F7 可以看到工程现在可以自行编译了,是不是和visual studio一模一样?

vscode-F7

由于我们现在是交叉编译,所以需要将执行文件传输到RPi上然后通过远程调试的方式来进行调试,这部分内容我们下节再讲。